package com.kehutong.material.service.impl;

import java.sql.Timestamp;
import java.time.LocalDateTime;

import com.kehutong.common.urlconfig.WebUrlConfig;
import com.kehutong.common.util.Token;
import com.kehutong.material.urlConfig.WorkerUrlConfig;
import org.coraframework.bean.Beans;
import org.coraframework.bean.valid.ValidResult;
import org.coraframework.http.HttpClient;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.connection.ThreadLocalCache;
import org.coraframework.threadpool.ThreadPool;
import org.coraframework.util.CallBack;

import com.kehutong.common.DoveClient;
import com.kehutong.common.errcode.ErrorCode;
import com.kehutong.common.urlconfig.FileUrlConfig;
import com.kehutong.material.entity.Material;
import com.kehutong.material.enums.MaterialType;
import com.kehutong.material.service.MaterialService;
import org.coraframework.util.Objects;
import org.coraframework.util.time.TimeUtil;

@WebService("/crm/material/service")
public class MaterialServiceImpl implements MaterialService {

    private static final Logger logger = LoggerFactory.getLogger(MaterialServiceImpl.class);

    @Inject
    private ThreadPool threadPool;
    @Inject
    private DoveClient doveClient;
    @Inject
    private FileUrlConfig fileUrlConfig;
    @Inject
    private JdbcSession jdbcSession;
    @Inject
    private WorkerUrlConfig workerUrlConfig;


    @Override
    @ReqMapping("/save")
    public Object save(JSONObject item, ValidResult result) {
        if (result.hasError("descrition","memory","type","fileId","fileType","isFolder","shareUrl", "userId", "media_id", "expiredTime", "content", "fileId")) {
            return com.kehutong.common.errcode.Result.error(0, result.getErrorMessage());
        }
        Material material = Pool.newInstance(Material.class);
        Beans.from(item).to(material).igornNull().copy();
        jdbcSession.insert(material);
        return material;
    }


    public void forwordFile(Material item) {
        try {
            MaterialType type = item.getType() == MaterialType.MINI_PROGRAM ? MaterialType.IMAGE : item.getType();

            //final String access_token = enterpriseService.getContactAccessToken(item.getCompanyNo());
            //final String access_token = enterpriseService.getContactAccessToken(item.getCompanyNo());
            //TODO 设置路径
            JSONObject dataJsonObject=doveClient.post("/xxx",(httpOne)->{
                //httpOne.addParam("companyNo",item.getCompanyNo());
            });
            final String access_token = dataJsonObject.getString("data");
            if (item.getType() == MaterialType.IMAGE ||
                item.getType() == MaterialType.FILE ||
                item.getType() == MaterialType.MINI_PROGRAM ||
                item.getType() == MaterialType.VIDEO) {

                forwordFile(access_token, item.getFileId(), type.getName(), json->{
                    final Timestamp exp = new Timestamp(json.getLongValue("created_at") * 1000L);
                    item.setMedia_id(json.getString("media_id"));
                    item.setExpiredTime(exp.toLocalDateTime().plusDays(3));
                    jdbcSession.updateById(item);
                });
            }
        } catch (Exception e) {
            logger.error("", e);
        }
    }

    @ReqMapping("/byId")
    public Object getMaterial(JSONObject jsonObject){
        Token token = jsonObject.getObject("token", Token.class);
        String id = jsonObject.getString("id");

        if (Objects.isNull(token)) {
            return Result.error(0, "请先登录");
        }

        Material material = Pool.get(Material.class, id);
        if (material == null || material.isDeleted()) {
            return Result.error(0, "文件不存在");
        }

        if (Objects.isNull(material.getMedia_id())) {
            syncForwordFile(token.getCompanyNo(), material);
            return Result.success(material);
        }

        if (Objects.nonNull(material.getExpiredTime()) &&
                material.getExpiredTime().isAfter(LocalDateTime.now())) {
            return Result.success(material);
        }

        syncForwordFile(token.getCompanyNo(), material);
        return Result.success(material);
    }



    public void forwordFile(String companyNo, Material item) {
        threadPool.execute(() -> {
            try {
                JSONObject dataJsonObject = doveClient.post("/kht-bin/wwout/agent/get", (httpOne) -> {
                    httpOne.addParam("companyNo", companyNo);
                });
                if (dataJsonObject.getIntValue("code") != 200) {
                    throw new Exception(dataJsonObject.getString("message"));
                }

                JSONObject data = dataJsonObject.getJSONObject("data");
                String access_token = data.getString("access_token");

                if (item.getType() == MaterialType.IMAGE || item.getType() == MaterialType.FILE || item.getType() == MaterialType.VIDEO) {
                    forwordFile(access_token, item.getFileId(), item.getType().getName(), json -> {
                        logger.info("forwordFile......{}", json);
                        final Timestamp exp = new Timestamp(json.getLongValue("created_at") * 1000L);
                        item.setMedia_id(json.getString("media_id"));
                        item.setExpiredTime(exp.toLocalDateTime().plusDays(3));
                        ThreadLocalCache.current().setCorpId(companyNo);
                        jdbcSession.updateById(item);
                    });
                }
            } catch (Exception e) {
                logger.error("", e);
            }
        });
    }

    public void syncForwordFile(String companyNo, Material item) {
        try {
            JSONObject dataJsonObject = doveClient.post("/kht-bin/wwout/agent/get", (httpOne) -> {
                httpOne.addParam("companyNo", companyNo);
            });
            if (dataJsonObject.getIntValue("code") != 200) {
                throw new Exception(dataJsonObject.getString("message"));
            }

            JSONObject data = dataJsonObject.getJSONObject("data");
            String access_token = data.getString("access_token");

            if (item.getType() == MaterialType.IMAGE || item.getType() == MaterialType.FILE || item.getType() == MaterialType.VIDEO) {
                forwordFile(access_token, item.getFileId(), item.getType().getName(), json -> {
                    logger.info("forwordFile......{}", json);
                    final Timestamp exp = new Timestamp(json.getLongValue("created_at") * 1000L);
                    item.setMedia_id(json.getString("media_id"));
                    item.setExpiredTime(exp.toLocalDateTime().plusDays(3));
                    ThreadLocalCache.current().setCorpId(companyNo);
                    jdbcSession.updateById(item);
                });
            }
        } catch (Exception e) {
            logger.error("", e);
        }
    }

    /**
     * 文件服务器转存文件
     * @param access_token
     * @param fileId
     * @param type
     * @param callBack
     * @return
     * @throws Exception
     */
    private ErrorCode forwordFile(String access_token, String fileId, String type, CallBack<JSONObject> callBack) throws Exception {
        final CallBack<HttpClient> httpCallBack = http -> {
            http.setReadTimeOut((int) TimeUtil.MILLIS_PER_MINUTE);
            http.addParam("url", workerUrlConfig.getEncodeUrl("/cgi-bin/media/upload"));
            http.addParam("fileId", fileId);
            http.addParam("type", type);
            http.addParam("access_token", access_token);
        };

        return fileUrlConfig.get("/file/forwardFile", httpCallBack, json -> callBack.call(json));
    }


}
